using System;
using System.Collections;
using UnityEngine;

namespace EventBehaviorTree
{
    [Serializable]
    public class AsyncSwitcher : Container<TriggerMode>
    {
        private bool _isWorking;
        private bool _toBeTrue;
        private bool _toBeFalse;
        public AsyncSwitcher()
        {
            _isWorking = false;
            _toBeTrue = true;
            _toBeFalse = true;
        }

        public AsyncSwitcher(Func<bool> condition)
        {
            _isWorking = false;
            _toBeTrue = true;
            _toBeFalse = true;
            Condition = condition;
        }

        public void SetCondition(Func<bool> condition) { Condition = condition; }

        protected override IEnumerator Worker()
        {
            SeniorNodeEvent(NodeMessage.Success);//start switcher successfully
            _isWorking = true;
            while (true)
            {
                if (Condition())
                {
                    if (_toBeTrue)
                    {
                        _subNodes[0].NodeEvent(NodeMessage.Start);
                        _toBeTrue = false;
                        _toBeFalse = true;
                    }
                }
                if (!Condition())
                {
                    if (_toBeFalse)
                    {
                        StopAllSubNodes();
                        _toBeFalse = false;
                        _toBeTrue = true;
                    }
                }
                yield return null;
            }
        }

        public override void NodeEvent(NodeMessage nodeMessage)
        {
            switch (nodeMessage)
            {
                case NodeMessage.Start:
                    if (_isWorking) return;//this node will not restart unless is not working
                    //Debug.Log(this + "/ " + Key);
                    _stepCount = 0;
                    if (Condition()) _subNodes[0].NodeEvent(NodeMessage.Start);//check for the first condition
                    ResetWorker();
                    _coroutineStarter.StartCoroutine(_worker);
                    return;
                case NodeMessage.Success:
                    if (_stepCount < _subNodes.Count - 1)
                    {
                        _subNodes[++_stepCount].NodeEvent(NodeMessage.Start);
                        return;
                    }
                    return;
                case NodeMessage.Failure:
                    return;
                case NodeMessage.COMMAND_Stop:
                    _isWorking = false;
                    StopAllSubNodes();
                    ResetWorker();
                    return;
                case NodeMessage.REQUEST_Abort:
                    _isWorking = false;
                    StopAllSubNodes();
                    ResetWorker();
                    SeniorNodeEvent(nodeMessage);
                    return;
                default:
                    break;
            }
        }
    }
}